#include "Buffer.hpp"

template Buffer<char>;

template<typename A>
Buffer<A>::Buffer(unsigned int size) :
_sizeMax(size),
_size(0)
{
	_data = new A[size * 2];
	_currentStart = 0;
	_end = 0;
}

template<typename A>
Buffer<A>::~Buffer()
{
	delete[] _data;
}

template<typename A>
int Buffer<A>::Write(A *data, unsigned int size)
{
	unsigned int i;
	if (this->_size + size > _sizeMax)
		return (-1);
	this->_size += size;
	for(i = 0; i < size; ++i)
	{
		this->_data[(this->_end + i) % this->_sizeMax] = data[i];
		if (this->_end + i >= this->_sizeMax)
			this->_data[(this->_end + i) % this->_sizeMax + this->_sizeMax] = data[i];
	}
	if (this->_size + size > _sizeMax)
	this->_end += size;
	return (0);
}


template<typename A>
unsigned int Buffer<A>::Size()
{
	return this->_size;
}

template<typename A>
unsigned int Buffer<A>::SizeMax()
{
	return this->_sizeMax;
}

template<typename A>
void Buffer<A>::Clean()
{
	_currentStart = 0;
	_end = 0;
	_size = 0;
}

template<typename A>
const A& Buffer<A>::operator[](unsigned int i)
{
	return _data[(this->_currentStart + i) % this->_sizeMax];
}


template<typename A>
int Buffer<A>::GoForward(unsigned int i)
{
	if (i <= this->_size)
	{
		this->_currentStart = (this->_currentStart + i)  % this->_sizeMax;
		return (0);
	}
	return (-1);
}

template<typename A>
A*  Buffer<A>::Read(unsigned int size)
{
	A *res = this->_data + this->_currentStart;
	this->_currentStart = (this->_currentStart + size)  % this->_sizeMax;
	this->_size -= size;
	return res;
}